package com.ztgf.search.server.service;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.ztgf.common.constant.CommonParameter;
import com.ztgf.common.constant.Result;
import com.ztgf.common.enums.CodeEnum;
import com.ztgf.common.utils.CustomizeUtil;
import com.ztgf.common.utils.Md5Utils;
import com.ztgf.common.utils.StrUtils;
import com.ztgf.db.utils.RedisUtil;
import com.ztgf.search.mapper.SearchUserMapper;
import com.ztgf.search.models.bo.SearchUserBO;
import com.ztgf.search.models.bo.SearchUserSaveBO;
import com.ztgf.search.models.dto.SearchIndexDTO;
import com.ztgf.search.models.dto.SearchUserDTO;
import com.ztgf.search.models.service.ISearchUserService;
import com.ztgf.search.models.vo.SearchUserVO;
import com.ztgf.search.server.config.YmlConfig;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;

/**
 * 搜索引擎系统用户表控制器
 *
 * @author chenyu.wang
 * @Date 2021-01-28 13:50:45
 */
@Slf4j
@DubboService
public class SearchUserServiceImpl extends ServiceImpl<SearchUserMapper, SearchUserDTO> implements ISearchUserService {

    @Resource
    private YmlConfig ymlConfig;
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private SearchIndexServiceImpl searchIndexService;

    @Override
    public boolean add(SearchUserSaveBO saveBO) {
        SearchUserDTO dto = new SearchUserDTO();
        BeanUtils.copyProperties(saveBO, dto);
        Long id = ymlConfig.getPkId();
        dto.setId(id);
        String salt = Md5Utils.createSalt();
        dto.setPassword(Md5Utils.MD5Encode(saveBO.getPassword().toUpperCase(), salt));
        dto.setSalt(salt);
        return this.insert(dto);
    }

    @Override
    public SearchUserDTO getUserBySession(String sessionId) {
        Object bean = redisUtil.getSession(sessionId, CommonParameter.getHeadParamsBO().getSource().toString());
        if (bean != null && bean instanceof SearchUserDTO) {
            return (SearchUserDTO) bean;
        }
        return null;
    }

    @Override
    public SearchUserDTO getUserBySession(Long userId) {
        String source = CommonParameter.getHeadParamsBO().getSource().toString();
        Object sessionId = redisUtil.getIdSessionRelation(userId + "", source);
        if (sessionId == null) {
            return null;
        }
        return this.getUserBySession(sessionId.toString());
    }

    @Override
    public void setUserSession(String sessionId, SearchUserDTO dto) {
        String source = CommonParameter.getHeadParamsBO().getSource().toString();
        if (dto != null) {
            Object oldSessionId = redisUtil.getIdSessionRelation(dto.getId().toString(), source);
            if (oldSessionId != null) {
                redisUtil.removeSession(oldSessionId.toString(), source);
            }
        }
        redisUtil.setSession(sessionId, dto, source);
        redisUtil.setIdSessionRelation(dto.getId().toString(), sessionId, source);
    }

    @Override
    public void delUserSession(String sessionId) {
        SearchUserDTO dto = getUserBySession(sessionId);
        if (dto != null) {
            String source = CommonParameter.getHeadParamsBO().getSource().toString();
            redisUtil.removeIdSession(dto.getId().toString(), source);
            redisUtil.removeSession(sessionId, source);
        }
    }

    @Override
    public void delUserSessionById(Long id) {
        SearchUserDTO searchUserDTO = selectById(id);
        if (searchUserDTO != null) {
            String source = CommonParameter.getHeadParamsBO().getSource().toString();
            Object idSessionRelation = redisUtil.getIdSessionRelation(id.toString(), source);
            if (null == idSessionRelation) {
                return;
            }
            redisUtil.removeIdSession(id.toString(), source);
            redisUtil.removeSession(idSessionRelation.toString(), source);
        }
    }

    @Override
    public boolean setResetUserSession(String sessionId) {
        SearchUserDTO dto = getUserBySession(sessionId);
        if (dto != null) {
            String source = CommonParameter.getHeadParamsBO().getSource().toString();
            redisUtil.setSession(sessionId, dto, source);
            redisUtil.setIdSessionRelation(dto.getId().toString(), sessionId, source);
            return true;
        }
        return false;
    }

    /**
     * @param oldPassword 旧密码
     * @param newPassword 新密码
     * @param name        用户名字
     * @return
     */
    @Override
    public Result<?> updateUserPassword(String oldPassword, String newPassword, String name) {
        String sessionId = CommonParameter.getHeadParamsBO().getSessionId();
        SearchUserDTO fileUserDTO = this.getUserBySession(sessionId);
        if (null == fileUserDTO) {
            return new Result<>(CodeEnum.FAIL_2);
        }
        fileUserDTO = this.selectById(fileUserDTO.getId());
        if (!Objects.equals(fileUserDTO.getPassword(),
                Md5Utils.MD5Encode(oldPassword.toUpperCase(), fileUserDTO.getSalt()))) {
            return new Result<>(CodeEnum.FAIL_USER_200001);
        }
        fileUserDTO.setPassword(Md5Utils.MD5Encode(newPassword.toUpperCase(), fileUserDTO.getSalt()));
        if (StrUtils.isNotEmpty(name)) {
            fileUserDTO.setName(name);
        }
        this.updateById(fileUserDTO);
        return new Result<>();
    }

    @Override
    public void resetSession(Long userId) {
        Object obj = redisUtil.getIdSessionRelation(userId.toString(), CommonParameter.getHeadParamsBO().getSource().toString());
        if (obj != null) {
            redisUtil.removeIdSession(obj.toString(), CommonParameter.getHeadParamsBO().getSource().toString());
            redisUtil.removeSession(obj.toString(), CommonParameter.getHeadParamsBO().getSource().toString());
        }
    }

    @Override
    public Page<SearchUserVO> queryIndexPageList(SearchUserBO bo) {
        Page<SearchUserVO> page = new Page<>(bo.getPageNo(), bo.getPageSize());
        List<SearchUserVO> list = baseMapper.queryIndexPageList(bo, page);
        if (CustomizeUtil.listIsNotNull(list)) {
            for (SearchUserVO searchUserVO : list) {
                // 查询索引条数
                Wrapper<SearchIndexDTO> wrapper = new EntityWrapper<>();
                wrapper.eq("user_id", searchUserVO.getId());
                int count = searchIndexService.selectCount(wrapper);
                searchUserVO.setIndexNum(count);
            }
            page.setRecords(list);
        }
        return page;
    }

}
